package com.medical.common.core.utils;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeUtils {
    // 默认时区配置
    private static final ZoneId SERVER_ZONE = ZoneId.of("Asia/Shanghai");
    private static final ZoneId UTC_ZONE = ZoneId.of("UTC");

    /**
     * 计算相对时间（支持多种时间类型）
     * 示例输出：刚刚 / 5分钟前 / 3小时前 / 昨天 / 5天前 / 3月前 / 2年前
     */
    public static String getRelativeTime(Object timeObj) {
        if (timeObj == null) return "";

        Instant instant = convertToInstant(timeObj);
        if (instant == null) return "";

        return calculateRelativeTime(instant);
    }

    // 统一转换为Instant时间
    private static Instant convertToInstant(Object timeObj) {
        if (timeObj instanceof Date) {
            return ((Date) timeObj).toInstant();
        } else if (timeObj instanceof LocalDateTime) {
            return ((LocalDateTime) timeObj).atZone(SERVER_ZONE).toInstant();
        } else if (timeObj instanceof Instant) {
            return (Instant) timeObj;
        } else if (timeObj instanceof ZonedDateTime) {
            return ((ZonedDateTime) timeObj).toInstant();
        }
        return null;
    }

    // 核心计算逻辑
    private static String calculateRelativeTime(Instant instant) {
        Instant now = Instant.now();
        if (instant.isAfter(now)) return "刚刚";

        Duration duration = Duration.between(instant, now);
        long seconds = duration.getSeconds();

        // 层级判断
        if (seconds < 60) return "刚刚";
        if (seconds < 3600) return unitString(seconds, TimeUnit.MINUTES, "分钟前");
        if (seconds < 86400) return unitString(seconds, TimeUnit.HOURS, "小时前");

        return calculateDayLevel(instant, now);
    }

    // 处理天级以上的时间差
    private static String calculateDayLevel(Instant instant, Instant now) {
        LocalDate startDate = instant.atZone(SERVER_ZONE).toLocalDate();
        LocalDate endDate = now.atZone(SERVER_ZONE).toLocalDate();

        long days = ChronoUnit.DAYS.between(startDate, endDate);
        if (days == 1) return "昨天";
        if (days <= 31) return days + "天前";

        return calculateMonthLevel(startDate, endDate);
    }

    // 处理月级以上的时间差
    private static String calculateMonthLevel(LocalDate start, LocalDate end) {
        Period period = Period.between(start, end);

        int totalMonths = period.getYears() * 12 + period.getMonths();
        if (start.getDayOfMonth() > end.getDayOfMonth()) {
            totalMonths--; // 处理不足整月的情况
        }

        if (totalMonths < 12) {
            return totalMonths + "月前";
        }

        int years = period.getYears();
        if (start.plusYears(years).isAfter(end)) {
            years--; // 处理不足整年情况
        }
        return years + "年前";
    }

    // 单位转换工具方法
    private static String unitString(long seconds, TimeUnit unit, String suffix) {
        long value = unit.convert(seconds, TimeUnit.SECONDS);
        return value + suffix;
    }

    /* 测试用例 */
    public static void main(String[] args) {
        // 测试数据（北京时间）
        testTime(LocalDateTime.now().minusMinutes(3));  // 3分钟前
        testTime(LocalDateTime.now().minusDays(1));     // 昨天
        testTime(LocalDateTime.of(2022,3,15,9,0).atZone(SERVER_ZONE).toInstant()); // 1年前
    }

    private static void testTime(Object time) {
        System.out.println(time + " => " + getRelativeTime(time));
    }
}
